<template>
    <div class="basic-container" :style="styleName">
        <!-- <el-card> -->
        <!--搜索插槽-->
        <slot v-if="hasSearchSlot" name="search"></slot>
        <div v-else class="tools">
            <search-form v-if="searchFilter" :searchFilter="searchFilter" @search="onSearch"></search-form>
            <div style="display:block;">
                <slot name="tools"></slot>
                <el-tooltip v-if="showTools" class="item" effect="dark" content="新增" placement="top-start">
                    <el-button icon="el-icon-plus" circle @click="onAdd" size="small"></el-button>
                </el-tooltip>
                <el-divider v-if="showTools" direction="vertical"></el-divider>
                <el-tooltip class="item" effect="dark" content="刷新" placement="top-start">
                    <el-button icon="el-icon-refresh" circle @click="refresh" size="small"></el-button>
                </el-tooltip>
            </div>
        </div>
        <!--表格前端显示统计数据-->
        <!-- <el-card v-if="showSummary" class="box-card">
                <div v-for="(item,k) in report" :key="k">
                    {{item.label}}：{{item.total}}
                </div>
            </el-card> -->
        <el-table v-loading="listLoading" :data="list" stripe highlight-current-row
            @selection-change="handleSelectionChange" @sort-change="sortChange" size="small" border>
            <el-table-column v-if="showSelection" align="center" type="selection" width="55"></el-table-column>
            <el-table-column v-for="(item, index) in cols" :key="index" :prop="item.field" :show-overflow-tooltip="true"
                :label="item.title" :min-width="item.width" v-bind="item.props" align="center">
                <template slot-scope="scope">
                    <!-- table switch -->
                    <bw-column :item="item" :row="scope.row" @update="onSave"></bw-column>
                </template>
            </el-table-column>
            <el-table-column v-if="showOption && options.length > 0" :width="options.length * 75 + 'px'" fixed="right"
                label="操作" align="center">
                <template slot-scope="scope">
                    <template v-for="(item, k) in options">
                        <el-button v-if="!item.validate || item.validate(scope.row)" :key="k" :type="item.type" size="small"
                            @click="reflect(item, scope.row)">{{ item.label }}
                        </el-button>
                    </template>

                </template>
            </el-table-column>
        </el-table>
        <pagination v-show="total > 0" :background="true" :total="total" :page.sync="listQuery.page"
            :limit.sync="listQuery.limit" @pagination="getList" />
        <!--编辑Dialog-->
        <edit-form ref="editForm" :editForm="editForm" :postForm="postForm" @onSave="onSave"></edit-form>
        <!-- </el-card> -->
    </div>
</template>
<script>
import request from 'axios'
import utils from '@/plugins/utils'
import Pagination from "@/components/Pagination";
import SearchForm from "./SearchForm";
import BwColumn from "./BwColumn";
import EditForm from "./EditForm";

export default {
    name: "CrudTable",
    components: {
        Pagination,
        SearchForm,
        BwColumn,
        EditForm,
    },
    props: {
        apiModel: String,
        cols: Array,
        searchFilter: Array,
        editForm: {
            type: Array | Object,
            default: () => [],
        },
        options: {
            type: Array,
            default: []
        },
        showOption: {
            type: Boolean,
            default: true,
        },
        showTools: {
            type: Boolean,
            default: true,
        },
        showSelection: {
            type: Boolean,
            default: false,
        },
        showSummary: {
            type: Boolean,
            default: false,
        },
    },
    beforeMount() {
        if (this.editForm) {
            this.editForm.forEach((val) => {
                if (val.dataType && val.dataType === "array") {
                    this.$set(this.postForm, val.field, []);
                } else {
                    this.$set(this.postForm, val.field, "");
                }
            });
        }
    },
    data() {
        return {
            // list: null,
            list: [
                {}
            ],
            total: 0,
            listLoading: false,
            listQuery: {
                page: 1,
                limit: 10,
            },
            editDialog: false,
            postForm: {
                id: 0,
            },
            multipleSelection: [],
            report: {}
        };
    },
    computed: {
        styleName() {
            return {
                borderRadius: 0,
                background: '#ffffff',
            }
        },
        hasSearchSlot() {
            if (this.$slots["search"] && this.$slots["search"].length > 0) {
                return true;
            }
            return false;
        },
    },
    created() {
        if (this.$route.query) {
            Object.assign(this.listQuery, this.$route.query);
        }
        // this.getList();
    },
    methods: {
        refresh() {
            this.getList();
        },
        async getList() {
            //this.listQuery = this.$filters.filterParams(this.listQuery);
            this.listLoading = true;
            const ret = await request({
                url: this.apiModel,
                method: "get",
                params: this.listQuery,
            });
            this.list = ret.data.data;
            this.total = ret.data.total ? ret.data.total : 0;
            this.report = ret.data.report ? ret.data.report : {}
            this.listLoading = false;
        },
        async onSearch(formData) {
            this.listQuery.page = 1;
            this.listQuery = { ...this.listQuery, ...formData };
            this.getList();
        },
        handleSelectionChange(val) {
            this.multipleSelection = val;
            this.$emit("select", val);
        },
        sortChange(val) {
            this.listQuery[val.prop] = val.order
            console.log(this.listQuery)
            this.getList();
        },
        /*函数调用中转*/
        reflect(item, params) {
            let method = item.method
            console.log(item, params)
            //调用方法存在该组件 直接调用否在上级组件调用
            if (Object.keys(this).includes(method)) {
                this[method](params);
            } else {
                if (typeof item.method === 'function') {
                    item.method(params);
                } else {
                    this.$emit(method, params);
                }
            }
        },
        onAdd() {
            if (Object.keys(this.$listeners).includes("add")) {
                this.$emit("add");
            } else {
                Object.keys(this.postForm).forEach((k) => {
                    this.postForm[k] = "";
                });
                this.$refs.editForm.editDialog = true;
            }
        },
        onEdit(row) {
            for (let i in this.postForm) {
                this.$set(this.postForm, i, row[i]);
            }
            this.$refs.editForm.editDialog = true;
        },
        //更新
        async onSave(item) {
            console.log(item)
            Object.keys(item).forEach((k) => {
                //提交字段是对象的情况下 json
                if ("object" === typeof item[k]) {
                    item[k] = JSON.stringify(item[k]);
                }
                if (item[k] === 'null') {
                    item[k] = null
                }
            });
            let method = "post",
                url = this.apiModel;
            if (item.id > 0) {
                url = url + "/" + item.id;
                method = "put";
            }
            const ret = await request({
                url: url,
                method: method,
                data: item,
            });
            if (ret.status === 200 || ret.status === 201) {
                this.$message({
                    type: "success",
                    message: '操作成功',
                });
                this.$refs.editForm.editDialog = false;
                this.getList();
            } else {
                this.$message({
                    type: "error",
                    message: ret.message,
                });
            }
        },
        onDelete(row) {
            utils.onDelete(this.apiModel + "/" + row.id, "getList", this);
        },
    },
};
</script>
<style lang="scss" scoped>
.tools {
    padding: 10px 0 0 0;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
}

.basic-container {
    padding: 10px 6px;
    box-sizing: border-box;

    &--block {
        height: 100%;

        .el-card {
            height: 100%;
        }
    }

    .el-card {
        width: 100%;
    }

    &:first-child {
        padding-top: 0;
    }
}

.box-card {
    margin-bottom: 10px;
}
</style>